04. Input & Output Streams

Input and Output Streams

In this section, you will learn how to read and write raw binary data using InputStreams and OutputStreams

ND079 JPND C2 L02 A05 Input And Output Streams V2

Reading and Writing Data in Java

In Java, the utilities for reading and writing data are built on top of each other. This diagram shows you what that means. When you use a BufferedReader to read lines of text, that buffered reader is reading from another underlying Reader that provides characters of text. That Reader, in turn, is itself using an InputStream behind the scenes to read the raw data.

**We Use Input/Output Streams to Work with Bytes**

We Use Input/Output Streams to Work with Bytes

Input and output streams are the lowest level utilities Java provides. They give you access to the raw data, in the form of bytes. This data can come from a file, from user input on the command-line, or from a network or other source. These are the lowest level APIs Java offers for reading or writing a stream of bytes.

We use them to:

  • access low-level bytes of data from input

  • write bytes to output

When would you need to write code that directly uses InputStreams and OutputStreams.

SOLUTION: When there's a need to access low-level bytes of data, like implementing a custom network protocol or file format.

InputStream Example

InputStream in =
   Files.newInputStream(Path.of("test"), StandardOpenOption.READ);
byte[] data = new byte[10];
while (in.read(data) != -1) {  // Returns the number of bytes read
  useData(data);
}
in.close();  // Close the "test" file

This code creates a file called "test" using newInputStream() method of the Files API. The code calls the read() method, which reads the data into a byte[] and returns the number of bytes that were read. If no bytes were read, it returns -1. This code will read the entire file, 10 bytes at a time, until the loop reaches the end of the file.

OutputStream Example

OutputStream out = Files.newOutputStream(Path.of("test"));
out.write("Hello, world!".getBytes());
out.close();  // Close the "test" file

The basic write() method only deals with bytes. It's pretty self-explanatory: you give the write() method a byte[], and it writes those bytes to the output stream.

Both code examples call the close() method, which we'll cover in more detail later in this lesson.

Input & Output Streams Code Demo

ND079 JPND C2 L02 A06 Input And Output Streams Demo

Demo Code: Ways to Copy a File

Reading and Writing the Data Directly

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;

public class CopyFile {
    public static void main(String[] args) throws IOException {

        InputStream in = Files.newInputStream(Path.of(args[0]));;
        OutputStream out = Files.newOutputStream(Path.of(args[1]));;

        byte[] data = new byte[10];
        while (in.read(data) != -1) {
            out.write(data);
        }
        in.close();
        out.close();
    }
}

Using InputStream.transferTo(OutputStream)

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;

public class InputOutputStreams {
    public static void main(String[] args) throws IOException {

        InputStream in = Files.newInputStream(Path.of(args[0]));;
        OutputStream out = Files.newOutputStream(Path.of(args[1]));;
        in.transferTo(out);
        in.close();
        out.close();
    }
}

Using the Files API

import java.io.IOException;
import java.nio.file.Path;

public final class CopyFile {
    public static void main(String[] args) throws IOException {
        Files.copy(Path.of(args[0]), Path.of(args[1]));
    }
}

How many bytes of data can be read from a single call to the InputStream.read(..) method?

SOLUTION:
  • 1
  • 10
  • 20
  • 2048